#include "app_pool.h"
#include "log/log.h"
#include "pthread.h"
#include "mqueue.h"
#include <stdlib.h>

static const char *mq_name = "/app_pool_mq";
static mqd_t mqd;
static pthread_t *threads;//线程池
static int thread_num;//线程数量

//在创建线程时被调用，阻塞获取队列中的任务并执行
static void *thread_func(void *arg)
{
    Task task;//同一函数被多次调用调用栈不会重复
    while (1)
    {
        ssize_t size = mq_receive(mqd, (char *)&task, sizeof(Task), NULL);
        if (size == sizeof(Task))
        {
            task.task_func(task.arg);
        }
        
    }
}
int app_pool_init(int size)
{
    //创建消息队列
    struct mq_attr attr;
    attr.mq_msgsize = sizeof(Task);
    attr.mq_maxmsg = 10;
    mqd = mq_open(mq_name, O_CREAT | O_RDWR, 0644, &attr);
    if (mqd == -1)
    {
        log_error("mq_open error");
        return -1;
    }
    
    //创建线程池
    thread_num = size;
    threads = (pthread_t *)malloc(sizeof(pthread_t) * size);
    for (int i = 0; i < size; i++)
    {
        pthread_create(&threads[i], NULL,thread_func, NULL);
    }

    return 0;
}

void app_pool_close(void)
{
    mq_close(mqd);
    mq_unlink(mq_name);

    for (size_t i = 0; i < thread_num; i++)
    {
        pthread_cancel(threads[i]);
        pthread_join(threads[i], NULL);
    }
    
    free(threads);
}

int app_pool_registerTask(int (*task_func)(void *arg), void *arg)
{
    //创建任务
    Task task;
    task.task_func = task_func;
    task.arg = arg;
    //把任务存入消息队列
    if (mq_send(mqd, (char *)&task, sizeof(Task), 0) == -1)
    {
        log_error("mq_send error");
        return -1;
    }
    return 0;
}
